#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "StdUdp.h"

struct StdUdpServer
{
    int sock;
};
UdpS *InitUdpS(const char *ip, unsigned short port)
{
    UdpS *s = (UdpS*)malloc(sizeof(UdpS));
    if(s == NULL)
        return NULL;

    s->sock = socket(AF_INET,SOCK_DGRAM,0);
    if(s->sock < 0)
    {
        perror("socket");
        free(s);
        return NULL;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;//IPV4协议族
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    if(bind(s->sock,(struct sockaddr*)&addr,sizeof(addr)) < 0)
    {
        perror("bind");
        close(s->sock);
        free(s);
        return NULL;
    }
    return s;
}

bool UdpSRecv(UdpS *s,void *ptr,size_t size)
{
    struct sockaddr_in clientAddr;
    socklen_t len = sizeof(clientAddr);

    if(recvfrom(s->sock,ptr,size,0,(struct sockaddr*)&clientAddr,&len) < 0)
    {
        perror("recvfrom");
        return false;
    }
    printf("客户端IP:%s 端口:%d\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
    return true;
}

bool UdpSSend(UdpS *s, const char *ip, unsigned short port, void *ptr, size_t size)
{
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;//IPV4协议族
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);

    if(sendto(s->sock,ptr,size,0,(struct sockaddr*)&addr,sizeof(addr)) < 0)
    {
        perror("sendto");
        return false;
    }
    return true;
}

void ClearUdpS(UdpS *s)
{
    if(s == NULL)
        return;
    
    close(s->sock);
    free(s);
}



struct StdUdpClient
{
    int sock;
    char ServerIP[16];
    unsigned short Port;
};

UdpC *InitUdpC(const char *ip, unsigned short port)
{
    UdpC *c = (UdpC*)malloc(sizeof(UdpC));
    if(c == NULL)
        return NULL;

    c->sock = socket(AF_INET,SOCK_DGRAM,0);
    if(c->sock < 0)
    {
        perror("socket");
        close(c->sock);
        free(c);
        return NULL;
    }

    strcpy(c->ServerIP,ip);
    c->Port = port;
    return c;
}

bool UdpCRecv(UdpC *c, void *ptr, size_t size)
{
    struct sockaddr_in clientAddr;
    socklen_t len = sizeof(clientAddr);

    if(recvfrom(c->sock,ptr,size,0,(struct sockaddr*)&clientAddr,&len) < 0)
    {
        perror("recvfrom");
        return false;
    }
    
    return true;
}

bool UdpCSend(UdpC *c, void *ptr, size_t size)
{
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;//IPV4协议族
    addr.sin_port = htons(c->Port);
    addr.sin_addr.s_addr = inet_addr(c->ServerIP);

    if(sendto(c->sock,ptr,size,0,(struct sockaddr*)&addr,sizeof(addr)) < 0)
    {
        perror("sendto");
        return false;
    }
    return true;
}

void ClearUdpC(UdpC *c)
{
    if(c == NULL)
        return;
    
    close(c->sock);
    free(c);
}
